package asteroids.model;

import asteroids.Util;
import be.kuleuven.cs.som.annotate.*;
import java.lang.Math;

/**
 * A class used to discribe two-dimensional vectors.
 * @author Martin & Anton
 * @invar	The values of x and y will always be valid values.
 * 			| Util.isValidDouble(getX()) && Util.isValidDouble(getY())
 */
public class Vector {
	
	public Vector(double x, double y) throws IllegalArgumentException{
		if(!Util.isValidDouble(x) || !Util.isValidDouble(y))
			throw new IllegalArgumentException();
		this.x = x;
		this.y = y;
	}

	private double x;
	private double y;
	
	@Basic
	public double getX(){
		return x;
	}
	
	@Basic
	public double getY(){
		return y;
	}
	
	/**
	 * Method to change the coordinates.
	 * @param x
	 * @param y
	 * @throws IllegalArgumentException
	 * 			If the input is not valid, an IllegalArgumentException is thrown.
	 * 			| if !(Util.isValidDouble(x) && Util.isValidDouble(y))
	 */
	public void setSpeed(double x, double y) throws IllegalArgumentException{
		if(Util.isValidDouble(x) && Util.isValidDouble(y)){
			this.x = x;
			this.y = y;
		}
		else{
			throw new IllegalArgumentException();
		}
	}
	
	/**
	 * Method to change the X-coordinate.
	 * @param input
	 * @throws IllegalArgumentException
	 * 			If the input is not valid, an IllegalArgumentException is thrown.
	 * 			| if !(Util.isValidDouble(input))
	 */
	public void setX(double input) throws IllegalArgumentException{
		if(Util.isValidDouble(input)){
			this.x = input;
		}
		else{
			throw new IllegalArgumentException();
		}
	}
	
	/**
	 * Method to change the Y-coordinate.
	 * @param input
	 * @throws IllegalArgumentException
	 * 			If the input is not valid, an IllegalArgumentException is thrown.
	 * 			| if !(Util.isValidDouble(input))
	 */
	public void setY(double input) throws IllegalArgumentException{
		if(Util.isValidDouble(input)){
			this.y = input;
		}
		else{
			throw new IllegalArgumentException();
		}
	}
	
	/**
	 * A method to get the angle which the coordinates are pointed, given by Math.atan.
	 * @return	If the x value is 0, gives back 0. Else gives back the ArcTan of y/x.
	 * 			| if(x=0)	return 0
	 * 			| else 		return Math.atan(y/x)
	 * 
	 */
	public double getDirection() {
		if(Util.fuzzyEquals(x, 0)) return 0;
		else return Math.atan(y/x);
	}
	
	/**
	 * Get the distance to another vector.
	 * @param other
	 * @return Math.sqrt( Math.pow(x-other.getX(), 2) + Math.pow(y-other.getY(), 2) )
	 * @throws NullPointerException
	 */
	public double getDistanceTo(Vector other) throws NullPointerException{
		return Math.sqrt( Math.pow(x-other.getX(), 2) + Math.pow(y-other.getY(), 2) );
	}
	
}